package com.kosugi.flickingcoin;

import java.util.List;
import java.util.Iterator;
import java.util.LinkedList;

import com.badlogic.gdx.graphics.GL10;

public class Shape {
	public Shape parent;

	public float[] pos = new float[3];
	public float[] vel = new float[3];
	public float[] acc = new float[3];
	
	public float[] color = new float[3];
	public float alpha = 1;
	
	public float friction = 1000f;
	
	void updatePosition(long t) {
		if(t == 0)
			return;
		
		updatePositionSelf(t);
		Iterator<Shape> it = children.iterator();
		
		while(it.hasNext()) {
			Shape sh = it.next();
			sh.updatePosition(t);
		}
	}
	
	void updatePositionSelf(long t) {
		
		float vlength = (float)Math.sqrt(vel[0] * vel[0] + 
										vel[1] * vel[1] + 
										vel[2] * vel[2]);

		if(vlength == 0)
			return;
		
		acc[0] = - vel[0] / vlength * friction;
		acc[1] = - vel[1] / vlength * friction;
		acc[2] = - vel[2] / vlength * friction;
		
		float alength = (float)Math.sqrt(acc[0] * acc[1] +
										acc[1] * acc[1] +
										acc[2] * acc[2]);
		
		
		float st = t * 0.0001f;

		
		if(vlength < alength * st) {
			acc[0] = acc[1] = acc[2] = 0f;
			vel[0] = vel[1] = vel[2] = 0f;
			return;
		}
		
		pos[0] += vel[0] * st + acc[0] * st * st;
		pos[1] += vel[1] * st + acc[1] * st * st;
		pos[2] += vel[2] * st + acc[2] * st * st;
		
		
		
		vel[0] += acc[0] * st;
		vel[1] += acc[1] * st;
		vel[2] += acc[2] * st;

		
	}
	
	public List<Shape> children;
	
	public Shape() {
		children = new LinkedList<Shape> ();
	}
	
	public boolean isHitted(float x, float y) {
		return false;
	}
	
	public Shape getHitted(float x, float y) {
		Iterator<Shape> it = children.iterator();
		
		while(it.hasNext()){
			Shape hitted = it.next().getHitted(x, y);
			if(hitted != null)
				return hitted;
		}
		
		if(isHitted(x, y))
			return this;
		
		return null;
	}
	
	public void setPosition(float x, float y, float z) {
		pos[0] = x;
		pos[1] = y;
		pos[2] = z;
	}
	
	public void setVelocity(float vx, float vy, float vz) {
		vel[0] = vx;
		vel[1] = vy;
		vel[2] = vz;
	}
	
	public void setColor(float r, float g, float b) {
		color[0] = r;
		color[1] = g;
		color[2] = b;
		
		updateGeometry();
	}
	
	public void setAlpha(float a) {
		alpha = a;
		updateGeometry();
	}
	
	public void updateGeometry(){}
	
	public void draw(GL10 gl){
		gl.glPushMatrix();
		
		gl.glTranslatef(pos[0], pos[1], pos[2]);
		
		Iterator<Shape> it = children.iterator();
		
		while(it.hasNext()){
			it.next().draw(gl);
		}
		
		drawSelf(gl);
		
		gl.glPopMatrix();
	}
	
	public void drawSelf(GL10 gl){}
	
	public boolean isParent(Shape s){
		return parent == s;
	}
	
	public boolean isChild(Shape s){
		int rslt = children.indexOf(s);
		if(rslt == -1)
			return false;
		else
			return true;
	}
	
	public void disconnectChild(Shape child){
		child.parent = null;
		
		children.remove(child);		
	}
	
	public void addChild(Shape child) {
		children.add(child);
	}
	
	static public void connect(Shape parent, Shape child){
		if(child.isParent(parent))
			return;
		
		parent.disconnectChild(child);
		
		parent.addChild(child);
		child.parent = parent;
	}
}
